package com.edu.control.deploy;

import com.edu.control.deploy.constant.Constants;
import com.edu.control.deploy.constant.DeployStatus;
import com.edu.control.deploy.constant.FaasCli;
import com.edu.control.deploy.retrytask.RetryTask;
import com.edu.control.deploy.retrytask.RetryTaskManager;
import com.edu.control.deploy.retrytask.impl.K8SFuncTask;
import com.edu.control.exception.FaasException;
import com.edu.control.k8s.KubernetesApi;
import com.edu.util.process.ProcessUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;

public class CommandActuator {

    private static final Logger LOGGER = LoggerFactory.getLogger(CommandActuator.class);

    private CommandActuator() {
    }

    public static void exec(FaasCli cli) throws Exception {
        try {
            Process exec = Runtime.getRuntime().exec(cli.getCommand());
            int result = exec.waitFor();
            if (Constants.PROCESS_SUCCESS != result) {
                String errorMsg = ProcessUtil.parseResult(result, exec, cli.getCommand());
                throw new RuntimeException(errorMsg);
            }
        } catch (Exception e) {
            LOGGER.error("faas-cli login error: {}", e.getMessage());
            throw e;
        }
    }

    public static void exec(FaasCli cli, PodInfo podInfo, String dir, KubernetesApi kubernetesApi, DeployStorage deployStorage, DeployStateSync deployStateSync) throws Exception {
        String key = podInfo.getFunctionName();
        try {
            Process exec = Runtime.getRuntime().exec(cli.getCommand() + podInfo.getPathName() + podInfo.getFunctionName() + cli.getSuffix(), null, dir == null ? null : new File(dir));
            setState(key, cli, deployStorage);
            int result = exec.waitFor();
            if (Constants.PROCESS_SUCCESS != result) {
                String errorMsg = ProcessUtil.parseResult(result, exec, cli.getCommand());
                setErrorState(key, errorMsg, deployStorage);
                throw new FaasException(errorMsg);
            } else {
                if (cli.getStatus().getCode() == DeployStatus.DEPLOY.getCode()) {
                    RetryTaskManager.addRetryTask(new RetryTask(new K8SFuncTask(podInfo, kubernetesApi, deployStorage, deployStateSync)));
                }
            }
        } catch (Exception e) {
            if (!(e instanceof FaasException)){
                setErrorState(key, e.getMessage(), deployStorage);
            }
            throw e;
        }
    }

    public static void exec(FaasCli cli, PodInfo podInfo, String dir, KubernetesApi kubernetesApi, DeployStorage deployStorage) throws Exception {
        exec(cli, podInfo, dir, kubernetesApi, deployStorage, null);
    }

    private static void setState(String key, FaasCli cli, DeployStorage deployStorage) {
        DeployResult deployResult = DeployResult.newDeployResult(cli.getStatus());
        deployStorage.store(key, deployResult);
    }

    private static void setErrorState(String key, String errorMsg, DeployStorage deployStorage) {
        DeployResult deployResult = DeployResult.newDeployResult(DeployStatus.FAILED);
        deployResult.setMsg(errorMsg);
        deployStorage.store(key, deployResult);
    }
}
